﻿using System;
using Microsoft.Data.Sqlite;
using MyTinnyApi.model;
using Newtonsoft.Json;
using Microsoft.Maui.Controls;
using TreeView.Maui.Core;
using System.Transactions;
using Microsoft.EntityFrameworkCore.Storage;

namespace MyTinnyApi.util
{
	public class ImportExportUtil
	{
		public static void ImportPostman(string filePath, string type)
		{
			var json = File.ReadAllText(filePath);
					var showOrder = 0;
			switch (type)
			{
				case ApiConstants.import_postman_env:
					var postmanEnv = JsonConvert.DeserializeObject<PostmanEnvRoot>(json);
					var env = new Env()
					{
						EnvName = postmanEnv.Name,
						ShowOrder = showOrder++,
						Values = postmanEnv.Values?.Select(d => new EnvDetail() { EnvCode = d.Key, EnvValue = d.Value, ShowOrder = showOrder++ }).ToList()
					};
					EnvUtil.InsertEnv(env);

					//using (var transaction = DbUtil.BeginTransaction())
					//{
					//	try
					//	{
					//		var id = DbUtil.ExecuteInsert($"insert into t_env (EnvName, ShowOrder) values (@p1, @p2)", new[]
					//		{
					//			new SqliteParameter("@p1", postmanEnv.Name),
					//			new SqliteParameter("@p2", showOrder++)
					//		});

					//		foreach (var v in postmanEnv.Values)
					//		{
					//			DbUtil.ExecuteInsert($"insert into t_env_detail (EnvId, EnvCode, EnvValue, ShowOrder) values (@p1, @p2, @p3, @p4)", new[]
					//			{
					//			new SqliteParameter("@p1", id),
					//			new SqliteParameter("@p2", v.Key),
					//			new SqliteParameter("@p3", v.Value),
					//			new SqliteParameter("@p4", showOrder++),
					//		});
					//		}
					//		transaction.Commit();
					//	}
					//	catch (Exception ex)
					//	{
					//		transaction.Rollback();
					//		throw ex;
					//	}
					//}
					break;
				case ApiConstants.import_postman_collection:
					var postmanColl = JsonConvert.DeserializeObject<PostmanCollectionRoot>(json);
					using (var db = new AppDbContext())
					{
						using(var tran = db.Database.BeginTransaction())
						{
							try
							{
								var folder = new Folder() { Name = postmanColl.info.name };
								folder.Id = FolderUtil.InserFolder(folder, db);
								foreach (var item in postmanColl.item)
								{
									InsertItem(item, db, folder.Id);
								}
								tran.Commit();
							}
							catch (Exception ex)
							{
								Console.WriteLine(ex.StackTrace);
								tran.Rollback();
								throw ex;
							}

						}
					}
					break;
			}
		}

		private static void InsertItem(PostmanCollectionItem item, AppDbContext db, int _ParentId)
		{
            if (item.item?.Count > 0)
            {
				//是一个folder
				var subId = FolderUtil.InserFolder(new Folder() { Name = item.name, ParentId = _ParentId }, db);
                foreach (var subItem in item.item)
                {
					InsertItem(subItem, db, subId);
                }
			}
			else
			{
				var pReq = item.request;
				var version = DateTime.Now.Millisecond;

				if(pReq?.url?.host == null || pReq?.url?.host?.Count <= 0)
				{
					return;
				}

				var url = string.IsNullOrWhiteSpace(pReq?.url?.protocol) ? "" : (pReq.url.protocol + "://");
				url += string.Join(".", pReq.url.host) + "/";
				if(pReq.url.path?.Count > 0)
				{
					url += string.Join("/", pReq.url.path);
				}

				var header = pReq.header.Select(h =>
				{
					return new RequestHeader() { HeaderVersion = version, HeaderName = h.key, HeaderValue = h.value, InUse = !h.disabled };
				}).ToList();

				var param = pReq.url.query?.Select(q =>
				{
					return new RequestParam() { ParamVersion = version, ParamName = q.key, ParamValue = q.value, InUse = !q.disabled };
				}).ToList();

				RequestBody body = null;
				if(pReq.body != null)
				{
					body = new RequestBody() { BodyType = pReq.body.mode, BodyContent = pReq.body.raw, BodyVersion = version };
					var bodyParam = pReq.body.formdata?.Select(f =>
					{
						return new RequestBodyParam() { ParamName = f.key, ParamValue = f.value ?? f.src, ParamVersion = version, InUse = !f.disabled, BodyType = f.type };
					}).ToList();
				}

                Requests req = new Requests()
				{
					FolderId = _ParentId,
					RequestName = item.name,
					RequestUrl = url,
					RequestMethod = pReq.method.ToUpper(),
					RequestHeaderList = header,
					RequestParamList = param,
					RequestBodyModel = body
				};

				RequestUtil.InsertRequest(req, db);
			}
        }
	}
}

